package controllers

import (
	"dmsv/common"
	"dmsv/etc"
	"dmsv/session"
	"dmsv/sipuser"
	"encoding/json"
	"fmt"
	"github.com/beego/beego/v2/core/logs"
	"os"
	"strconv"
	"strings"
)

type SipController struct {
	BaseController
}

func (this *SipController) URLMapping() {
	this.Mapping("add", this.SipAcctAdd)
	this.Mapping("del", this.SipAcctDel)
	this.Mapping("update", this.SipAcctUpdate)
}

// @Title
// @Description 添加一个sip账号
// @Param   param   body   controllers.SipAcctParam     true   "sip账号相关信息"
// @Success 200 {object}   controllers.Code        ""
// @router /add [post]
func (this *SipController) SipAcctAdd() {

	params := SipAcctParam{}
	if err := json.Unmarshal(this.Ctx.Input.RequestBody, &params); err != nil {
		this.Data["json"] = ParamsError
		this.ServeJSON()
		return
	}

	err := common.CreateSipAcountFile(params.SipAcct, params.Passwd, etc.Conf.Fs.AcctDir)
	if err != nil {
		this.Data["json"] = MakeSysErrCode(err.Error())
		this.ServeJSON()
		return
	}

	err = session.LoadSipAcct()
	if err != nil {
		this.Data["json"] = MakeSysErrCode(err.Error())
		this.ServeJSON()
		return
	}

	logs.Debug("添加sip账号成功,appId:%v,账号:%v", params.AppId, params.SipAcct)

	this.Data["json"] = Success
	this.ServeJSON()
	return
}

// @Title
// @Description 更新sip账号信息:修改密码，或者删除
// @Param   param   body   controllers.SipAcctParam     true   "sip账号相关信息"
// @Success 200 {object}   DefaulController.Result        ""
// @router /update [post]
func (this *SipController) SipAcctUpdate() {

	params := SipAcctParam{}
	if err := json.Unmarshal(this.Ctx.Input.RequestBody, &params); err != nil {
		this.Data["json"] = ParamsError
		this.ServeJSON()
		return
	}

	_, err := strconv.Atoi(params.SipAcct)
	if err != nil {
		this.Data["json"] = SipIdError
		this.ServeJSON()
		return
	}

	err = common.CreateSipAcountFile(params.SipAcct, params.Passwd, etc.Conf.Fs.AcctDir)
	if err != nil {
		this.Data["json"] = MakeSysErrCode(err.Error())
		this.ServeJSON()
		return
	}

	//重新加载xml
	err = session.LoadSipAcct()
	if err != nil {
		this.Data["json"] = MakeSysErrCode(err.Error())
		this.ServeJSON()
		return
	}
	logs.Debug("修改sip账号成功,appId:%v,账号:%v", params.AppId, params.SipAcct)

	this.Data["json"] = Success
	this.ServeJSON()
	return
}

// @Title
// @Description
// @Param   param   body   controllers.SipAcctParam     true   "sip账号相关信息"
// @Success 200 {object}   DefaulController.Result        ""
// @router /del [post]
func (this *SipController) SipAcctDel() {

	params := SipAcctParam{}
	if err := json.Unmarshal(this.Ctx.Input.RequestBody, &params); err != nil {
		this.Data["json"] = ParamsError
		this.ServeJSON()
		return
	}

	fileName := fmt.Sprintf("%s/%s.xml", etc.Conf.Fs.AcctDir, params.SipAcct)
	_, err := os.Stat(fileName)
	if err != nil {
		if !strings.Contains(err.Error(), "no such") {
			this.Data["json"] = MakeSysErrCode(err.Error())
			this.ServeJSON()
			return
		}
	} else {
		err = os.Remove(fileName)
		if err != nil {
			this.Data["json"] = MakeSysErrCode(err.Error())
			this.ServeJSON()
			return
		}
	}

	err = session.LoadSipAcct()
	if err != nil {
		this.Data["json"] = MakeSysErrCode(err.Error())
		this.ServeJSON()
		return
	}

	err = session.DelRegAcct(params.SipAcct, etc.Conf.Fs.Domain)
	if err != nil {
		this.Data["json"] = MakeSysErrCode(err.Error())
		this.ServeJSON()
		return
	}

	logs.Debug("删除sip账号成功,appId:%v,账号:%v", params.AppId, params.SipAcct)

	this.Data["json"] = Success
	this.ServeJSON()
	return
}

// @Title
// @Description
// @Param   param   formData   ""     true   "注册相关信息"
// @Success 200 {object}   controllers.Code        ""
// @Failure 400
// @Failure 404
// @router /sipReg [post]
func (this *SipController) SipReg() {

	logs.Debug("new request to url:%v,content :%v", this.Ctx.Request.URL, string(this.Ctx.Input.RequestBody))

	err := this.Ctx.Request.ParseForm()
	if err != nil {
		logs.Error("parse failed:%v", err)
	}

	sipAccount := this.GetString("sip_auth_username")
	if sipAccount == "" {
		logs.Error("sipAccount is nil")
		return
	}

	user := sipuser.GetUser(sipAccount)
	if user.Password == "" || user.Account == "" {
		logs.Error("sipAccount:%v is invalid", sipAccount)
		return
	}

	logs.Debug("get user :%v", user)

	resp := "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" +
		"<document type=\"freeswitch/xml\">\n" +
		"  <section name=\"directory\">\n" +
		"    <domain name=\"192.168.11.244\">\n" +
		fmt.Sprintf("    <user id=\"%s\">\n", sipAccount) +
		"        <params>\n" +
		fmt.Sprintf("          <param name=\"password\" value=\"%s\"/>\n", user.Password) +
		"          <param name=\"dial-string\" value=\"{sip_invite_domain=${dialed_domain},presence_id=${dialed_user}@${dialed_domain}}${sofia_contact(${dialed_user}@${dialed_domain})}\"/>\n" +
		"        </params>\n" +
		"        <variables>\n" +
		fmt.Sprintf("          <variable name=\"user_context\" value=\"%s\"/>\n", sipAccount) +
		"          <variable name=\"sip-force-contact\" value=\"NDLB-connectile-dysfunction-2.0\"/>" +
		"          <variable name=\"toll_allow\" value=\"domestic,international,local\"/>\n" +
		fmt.Sprintf("          <variable name=\"accountcode\" value=\"%s\"/>\n", sipAccount) +
		fmt.Sprintf("          <variable name=\"effective_caller_id_name\" value=\"Extension %s\"/>\n", sipAccount) +
		fmt.Sprintf("          <variable name=\"effective_caller_id_number\" value=\"%s\"/>\n", sipAccount) +
		"          <variable name=\"outbound_caller_id_name\" value=\"\"/>\n" +
		"          <variable name=\"outbound_caller_id_number\" value=\"\"/>\n" +
		"          <variable name=\"callgroup\" value=\"techsupport\"/>\n" +
		"        </variables>\n" +
		"      </user>\n" +
		"    </domain>\n" +
		"  </section>\n" +
		"</document>"

	logs.Debug("send:%v", resp)
	this.Ctx.Output.Header("Content-Type", "application/xml; charset=utf-8")
	err = this.Ctx.Output.Body([]byte(resp))
	if err != nil {
		logs.Error("send err:%v", err)
	}

	return
}
